/************************************************************
 * Project Name         [Thinking_In_Java]
 * File Name            [ConsoleCalculator.java]
 * Creation Date        [10-Jul-2014]
 * 
 * Copyright© ge.y.yang@gmail.com All Rights Reserved
 * 
 * Work hard, play harder, think big and keep fit
 ************************************************************/
package pkg_01_console_app.calculator;

import java.io.IOException;

import pkg_01_console_app.util.ConsoleInput;

/**
 * 该类是一个控制台计算器类<br>
 * 该计算器主要实现的功能有: 加法运算, 减法运算, 乘法运算, 除法运算, 阶乘运算, 打印斐波那契数列, 十六进制转换为十进制, 十进制转换为十六进制
 * 
 * @author 不落的太阳(Sean Yang)
 * @version 1.0
 * @since JDK 6
 * 
 */
public class ConsoleCalculator {

	/**
	 * 控制台版本计算器运行主程序
	 * 
	 * @param args
	 *            运行程序时在参数列表输入相应的参数, 就可以直接跳过提示信息, 直接操作, 例如: <br>
	 *            java ConsoleCalculator 1 <br>
	 * 
	 *            表示直接进行加法运算, 有效的参数有以下九种: <br>
	 *            1---加法运算<br>
	 *            2---减法运算<br>
	 *            3---乘法运算<br>
	 *            4---除法运算<br>
	 *            5---阶乘运算<br>
	 *            6---打印斐波那契数列<br>
	 *            7---十六进制转换为十进制<br>
	 *            8---十进制转换为十六进制<br>
	 *            9---程序退出<br>
	 */
	public static void main(String[] args) throws IOException,
			NumberFormatException {
		int input = 0;
		boolean use = true; // 标识用户是否继续使用计算器的变量, true为继续使用, false用户退出
		printWelcomMessage(); // 打印欢迎信息

		if (args != null && args.length > 0) { // 判断用户运行时是否使用了参数
			try {
				input = Integer.parseInt(args[0]);
			} catch (Exception e) {
				System.out.println("参数格式错误! ");
				use = false;
			}
		}

		while (use) { // 当确定继续使用计算器时, 循环执行程序
			String inputStrA, inputStrB; // 字符串格式的输入变量
			int inputIntA, inputIntB; // 整数格式的输入变量
			double inputDoubleA, inputDoubleB; // 小数形式的输入变量

			if (input < 1 || input > 9) { // 如果用户未输入有效的选择信息, 提示用户输入
				printMenu(); // 打印菜单界面
				input = ConsoleInput.inputInt("请选择一个操作: ");
			}
			switch (input) { // 根据用户输入的选择信息, 进行相应的操作
			case 1: // 加法运算
				inputStrA = ConsoleInput.inputString("请输入被加数: ");
				inputStrB = ConsoleInput.inputString("请输入加数: ");
				try { // 尝试使用整数来接收键盘输入的数
					inputIntA = Integer.parseInt(inputStrA);
					inputIntB = Integer.parseInt(inputStrB);
					System.out.println(inputIntA + "+" + inputIntB + "="
							+ MathCalculator.add(inputIntA, inputIntB));
				} catch (Exception e) { // 若转换出现异常, 证明输入的是浮点数, 用浮点数接收键盘输入的数
					inputDoubleA = Double.parseDouble(inputStrA);
					inputDoubleB = Double.parseDouble(inputStrB);
					System.out.println(inputDoubleA + "+" + inputDoubleB + "="
							+ MathCalculator.add(inputDoubleA, inputDoubleB));
				}
				break;
			case 2: // 减法运算
				inputStrA = ConsoleInput.inputString("请输入被减数: ");
				inputStrB = ConsoleInput.inputString("请输入减数: ");
				try { // 尝试使用整数来接收键盘输入的数
					inputIntA = Integer.parseInt(inputStrA);
					inputIntB = Integer.parseInt(inputStrB);
					System.out.println(inputIntA + "－" + inputIntB + "="
							+ MathCalculator.substract(inputIntA, inputIntB));
				} catch (Exception e) { // 若转换出现异常, 证明输入的是浮点数, 用浮点数接收键盘输入的数
					inputDoubleA = Double.parseDouble(inputStrA);
					inputDoubleB = Double.parseDouble(inputStrB);
					String inputPrefix = inputDoubleA + "－" + inputDoubleB
							+ "=";
					System.out.println(inputPrefix
							+ MathCalculator.substract(inputDoubleA,
									inputDoubleB));
				}
				break;
			case 3: // 乘法运算
				inputStrA = ConsoleInput.inputString("请输入被乘数: ");
				inputStrB = ConsoleInput.inputString("请输入乘数: ");
				try { // 尝试使用整数来接收键盘输入的数
					inputIntA = Integer.parseInt(inputStrA);
					inputIntB = Integer.parseInt(inputStrB);
					System.out.println(inputIntA + "×" + inputIntB + "="
							+ MathCalculator.multiply(inputIntA, inputIntB));
				} catch (Exception e) { // 若转换出现异常, 证明输入的是浮点数, 用浮点数接收键盘输入的数
					inputDoubleA = Double.parseDouble(inputStrA);
					inputDoubleB = Double.parseDouble(inputStrB);
					System.out.println(inputDoubleA
							+ "×"
							+ inputDoubleB
							+ "="
							+ MathCalculator.multiply(inputDoubleA,
									inputDoubleB));
				}
				break;
			case 4: // 除法运算
				inputStrA = ConsoleInput.inputString("请输入被除数: ");
				inputStrB = ConsoleInput.inputString("请输入除数: ");
				try { // 尝试使用整数来接收键盘输入的数
					inputIntA = Integer.parseInt(inputStrA);
					inputIntB = Integer.parseInt(inputStrB);
					System.out.println(inputIntA + "÷" + inputIntB + "="
							+ MathCalculator.divide(inputIntA, inputIntB));
				} catch (Exception e) { // 若转换出现异常, 证明输入的是浮点数, 用浮点数接收键盘输入的数
					inputDoubleA = Double.parseDouble(inputStrA);
					inputDoubleB = Double.parseDouble(inputStrB);
					System.out
							.println(inputDoubleA
									+ "÷"
									+ inputDoubleB
									+ "="
									+ MathCalculator.divide(inputDoubleA,
											inputDoubleB));
				}
				break;
			case 5: // 阶乘运算
				int a = ConsoleInput.inputInt("请输入要计算阶乘的数: ");
				System.out.println(a + "!=" + MathCalculator.factorial(a));
				break;
			case 6: // 打印斐波那契数列
				int n = ConsoleInput.inputInt("请输入斐波那契数列的项数: ");
				System.out.println("斐波那契数列的前" + n + "项为:");
				MathCalculator.fibonacciRecursion(n);
				break;
			case 7: // 十六进制转换为十进制
				String hex = ConsoleInput.inputString("请输入一个十六进制数: ");
				System.out.println(hex + "转换成十进制为: "
						+ MathCalculator.toDec(hex));
				break;
			case 8: // 十进制转换为十六进制
				int dec = ConsoleInput.inputInt("请输入一个十进制数: ");
				System.out.println(dec + "转换成十进制为: "
						+ MathCalculator.toHex(dec));
				break;
			case 9:
				use = false; // 程序退出
				break;
			default:
				System.out.println("无效的输入! ");
				break;
			}
			input = 0;
		}
		System.out.println("******谢谢使用******");

	}

	/**
	 * 打印计算器菜单界面
	 */
	private static void printMenu() {
		System.out.println("┏━━━━━━━━━━━━┓");
		System.out.println("┃               控制台计算器               ┃");
		System.out.println("┣━━━━━━━━━━━━┫");
		System.out.println("┃1. 加法运算                                ┃");
		System.out.println("┃2. 减法运算                                ┃");
		System.out.println("┃3. 乘法运算                                ┃");
		System.out.println("┃4. 除法运算                                ┃");
		System.out.println("┃5. 阶乘运算                                ┃");
		System.out.println("┃6. 打印斐波那契数列            ┃");
		System.out.println("┃7. 十六进制转换十进制       ┃");
		System.out.println("┃8. 十进制转换十六进制       ┃");
		System.out.println("┃9. 退出                                          ┃");
		System.out.println("┗━━━━━━━━━━━━┛");
	}

	/**
	 * 打印欢迎信息
	 */
	private static void printWelcomMessage() {
		System.out.println("*****************************");
		System.out.println("***欢迎使用控制台版本计算器***");
		System.out.println("*****************************");
	}

}
